﻿package com.pandemicode.framework.configuration {
	import com.pandemicode.framework.xml.XMLLoader;
	import org.osflash.signals.Signal;
	
	/**
	* @author Michael Lawrence
	* @version 1.0.0
	*/
	public class Config {
		private var _xmlFile:String;
		private var _xml:XMLLoader;
		private var _isLoaded:Boolean = false;
		private var _configLoaded:Signal;
		
		public function get configLoaded():Signal { return this._configLoaded; }
		
		/**
		 * Whether the Config instance has finished loading.
		 * @default false
		 */
		public function get isLoaded():Boolean { return this._isLoaded; }
		
		/**
		 * A configuration class for mapping an xml file to project settings.  This class is meant to be extended upon.
		 * @example
			<br/><strong>config.xml</strong>
			<pre>
				&lt;?xml version="1.0" encoding="utf-8" ?&gt;
				&lt;Data&gt;
					&lt;Version&gt;1.0.0&lt;/Version&gt;
				&lt;/Data&gt;
			</pre>
			<strong>ProjectConfig.as</strong>
			<pre>
				package com.pandemicode.configTest.configuration {
					import com.pandemicode.framework.configuration.Config;
					import com.pandemicode.framework.xml.XMLLoader;

					public class ProjectConfig extends Config {
						private var _version:String = "";
						
						public function get version():String { return this._version; }
						
						private static const instance:ProjectConfig = new ProjectConfig(SingletonLock);
						public static function get instance():ProjectConfig {
							return _instance;
						}
						
						public function ProjectConfig(lock:Class):void {
							// Verify that the lock is the correct class reference.
							if ( lock != SingletonLock )
								throw new Error("Invalid Singleton access.  Use ProjectConfig.instance." );
						}
						
						override protected function loadSettings(document:XML):void {
							super.loadSettings(document);
							
							this._version = String(document.version);
						}
					}
				}
				
				class SingletonLock { }
			</pre>
		 */
		public function Config() {
			this._configLoaded = new Signal(Config);
		}
		
		/**
		 * Loads the specified XML file.
		 * @param	xmlFile		The xml file to load that contains the project settings.
		 */
		public function load(xmlFile:String = "config.xml"):void {
			this._xml = new XMLLoader(xmlFile);
			this._xml.xmlLoadCompleted.add(this._xmlLoaderComplete);
		}
		
		/**
		 * Occurs once the xml has finished loading.
		 * @param	document	The xml document loaded.
		 */
		private function _xmlLoaderComplete(document:XML):void {
			if (this.loadSettings(document))
				this.configLoadComplete();
		}
		
		/**
		 * Can be overriden.  This occurs once the entire configuration has been loaded and is complete.
		 */
		protected function configLoadComplete():void {
			this._xml.xmlLoadCompleted.remove(this._xmlLoaderComplete);
			this._isLoaded = true;
			this._configLoaded.dispatch(this);
		}
		
		/**
		 * Meant to be overriden.  This should contain the logic to parse the XML document and apply them to the class's properties.
		 * @param	document	The XML document that was loaded.
		 * @return	Returns whether or not to automatically call configLoadComplete.
		 */
		protected function loadSettings(document:XML):Boolean {
			// Override this to load the settings from the xml file.
			return true;
		}
	}
}
